<template>
  <!-- 追溯图 -->
  <div class="container">
    <div class="toolbar">
      <div v-for="item in toolbar" :key="item.key" class="toolbarDiv">
        <div
          :class="{
            toolbarItem: true,
            [item.type]: true,
            disabled:
              !graph ||
              (item.type === 'button' &&
                !['legend', 'contentSet'].includes(item.name) &&
                !selectedNode)
          }"
          :style="{ width: item.width }"
          @click="!!graph && btnClick(item)"
        >
          <a-dropdown
            v-if="item.type === 'checkList'"
            class="_dropdown"
            :trigger="['click']"
          >
            <a-tooltip placement="bottom" :mouseEnterDelay="1">
              <template slot="title">
                {{ item.tips }}
              </template>
              <div>
                <div :class="`icon icon_${item.name}`"></div>
                <span v-if="item.des">{{ item.des }}</span>
                <a-icon type="down" />
              </div>
            </a-tooltip>
            <a-menu slot="overlay" class="checkList">
              <a-checkbox-group
                v-if="item.columnIds.length !== 0"
                :options="item.columnIds"
                :value="selectedColumnIds"
                @change="onChange"
              >
                <span slot="label" slot-scope="{ label }">{{ label }}</span>
              </a-checkbox-group>
            </a-menu>
          </a-dropdown>
          <a-dropdown
            v-else-if="item.type === 'buttonList'"
            class="_dropdown"
            :trigger="['click']"
          >
            <a-tooltip placement="bottom" :mouseEnterDelay="1">
              <template slot="title">
                {{ item.tips }}
              </template>
              <div class="itemContent">
                <div :class="`icon icon_${item.name}`"></div>
                <div style="margin-right: 2px">{{ item.des }}</div>
                <a-icon type="down" />
              </div>
            </a-tooltip>
            <a-menu slot="overlay" class="buttonList">
              <a-menu-item
                v-for="subItem in item.children"
                :key="subItem.key"
                :disabled="subItem.disabled && !selectedNode"
                @click="subItem.fn"
              >
                {{ subItem.name }}
              </a-menu-item>
            </a-menu>
          </a-dropdown>
          <div v-if="item.type === 'numberInput'" class="numberInput">
            <span>{{ item.label }}</span>
            <a-input-number
              id="inputNumber"
              v-model="traceHierarchy"
              size="small"
              :min="1"
              :max="99"
              @change="onNumberInputChange"
            />
          </div>
          <div v-if="item.type === 'button'">
            <a-tooltip placement="bottom" :mouseEnterDelay="1">
              <template v-if="item.name !== 'topiconline'" slot="title">
                {{ item.tips }}
              </template>
              <div :class="`icon icon_${item.name} `"></div>
            </a-tooltip>
          </div>
          <div v-if="item.type === 'button'">{{ item.des }}</div>
          <div v-if="item.type === 'zoom'">
            <div :class="`icon icon_zoomOut `" @click="zoomCanvas(false)"></div>
            <span
              style="marginLeft:4px;marginRight:4px"
            >{{ Math.floor(canvasZoom * 100) }}%</span
            >
            <div :class="`icon icon_zoomIn `" @click="zoomCanvas(true)"></div>
          </div>
        </div>
        <div v-if="item.line" class="iconbarline">
          <img src="statics/icons/app/barline.svg" />
        </div>
      </div>
    </div>
    <div class="subtool">
      <div v-show="contentSetShow" class="subBar">
        <div class="subBarItem">
          <span>关系类型</span>
          <a-input
            :value="relationTypeInput"
            style="width:70%"
            placeholder="请选择"
            readOnly
          >
            <img
              slot="suffix"
              src="statics/icons/app/iconmore.png"
              style="cursor:pointer"
              @click="toggleRelationTypeModal"
            />
          </a-input>
        </div>
        <div class="subBarItem">
          <span>需求类型</span>
          <a-input
            :value="requementTypeInput"
            style="width:70%"
            placeholder="全部需求类型"
            readOnly
          >
            <img
              slot="suffix"
              src="statics/icons/app/iconmore.png"
              style="cursor:pointer"
              @click="toggleElementTypeModal"
            />
          </a-input>
        </div>
        <div class="subBarItem">
          <span>范围</span>
          <a-input
            :value="relationScope"
            style="width:70%"
            placeholder="整个项目"
            readOnly
          >
            <img
              slot="suffix"
              src="statics/icons/app/iconmore.png"
              style="cursor:pointer"
              @click="toggleScopeModal"
            />
          </a-input>
        </div>
      </div>
      <div v-show="searchBarShow" class="subBar _search">
        <div class="subBarItem">
          <span>搜索</span>
          <div>
            <a-input-search
              allow-clear
              placeholder="请输入搜索内容"
              style="width:70%"
              enter-button
              @search="onSearch"
            />
            <span
              v-if="searchResult > 0"
            >共{{ searchResult }}处搜索结果</span
            >
          </div>
        </div>
      </div>
    </div>
    <div v-if="showGraph" class="graph">
      <div :id="this.diagram.id" ref="mountNode" style="height:100%"></div>
      <div v-show="showLegend" v-drag class="legends">
        <div class="title">图例</div>
        <div v-for="item in legend" :key="item.key" style="height:20px">
          <div
            class="legend"
            :style="{
              borderBottomStyle: item.style.border,
              borderBottomWidth: '3px',
              borderBottomColor: item.style.color,
              display: 'inline-block'
            }"
          ></div>
          <div style="display:inline-block">{{ item.name }}</div>
        </div>
      </div>
    </div>
    <div
      v-else
      class="empty"
      @drop="dragHandler"
      @dragover="handleTreeDragMouseover"
    >
      <img src="statics/images/sysml/icondownload.svg"/>
      <!-- <a-icon type="download" style="fontSize:40px;color: #919191;" /> -->
      <div class="text" style="margin-top:32px;">将需求拖拽至此区域</div>
    </div>
  </div>
</template>
<script>
import treeUtil from '.././ModelTree/treeUtil';
import { modelApi } from 'src/api/model/modelApi';
import { throttle, debounce } from 'lodash';
import { relationTypeModal } from './Modal/RelationType';
import { elementTypeModal } from './Modal/ElementType';
import { ContextMenu } from 'components/common/ContextMenu/index';
import { selectMutiple } from 'components/Attribute/modals/SelectMutiple';
import utils from './utils';
import { difference } from 'lodash';
import { SysMLUtilHelper } from "@/api/sysml-imports";
import { actions } from 'src/pages/mxgraph/Actions';
export default {
  name: 'requirement-relation-map',
  components: {},
  directives: {
    drag: {
      //// 指令的定义
      bind: function(el) {
        let odiv = el; //// 获取当前元素
        odiv.onmousedown = e => {
          //// 算出鼠标相对元素的位置
          let disX = e.clientX - odiv.offsetLeft;
          let disY = e.clientY - odiv.offsetTop;

          document.onmousemove = e => {
            //// 用鼠标的位置减去鼠标相对元素的位置，得到元素的位置
            let left = e.clientX - disX;
            let top = e.clientY - disY;
            odiv.style.left = left + 'px';
            odiv.style.top = top + 'px';
          };
          document.onmouseup = e => {
            document.onmousemove = null;
            document.onmouseup = null;
          };
        };
      }
    }
  },
  props: {
    'map-id': String,
    visible: Boolean
  },

  data() {
    return {
      value: 1,
      graph: null,
      selectedNode: null, //// 当前选中的行数据
      contentSetShow: true,
      searchBarShow: false,
      showGraph: false,
      relationScope: '',
      requementTypeInput: '',
      layoutDirection: 'H',
      traceDirection: 'INCOMING',
      canvasZoom: 1,
      diagram: null,
      traceHierarchy: 99,
      rootReq: null, //// 根需求
      tooltips: {
        x: 0,
        y: 0
      },
      searchResult: 0,
      selectedColumnIds: [],
      showTooltip: false,
      currentText: '',
      showLegend: false,
      events: {
        'project-modified': this.refreshMap,
        'model-add': this.refreshMap,
        'model-update': this.refreshMap,
        'model-delete': this.refreshMap
      },
      legend: [
        {
          key: 'Trace',
          name: '追踪',
          isVisible: true,
          icon: 'Trace',
          style: { color: '#5AD8A6', border: 'solid' }
        },
        {
          key: 'Refine',
          name: '精化',
          icon: 'Refine',
          isVisible: true,
          style: { color: '#F6BD16', border: 'solid' }
        },
        {
          key: 'Copy',
          name: '复制',
          icon: 'Copy',
          isVisible: true,
          style: { color: '#E8684A', border: 'solid' }
        },
        {
          key: 'DeriveReqt',
          name: '派生',
          isVisible: true,
          icon: 'DeriveReqt',
          style: { color: '#5D7092', border: 'solid' }
        },
        {
          key: 'Containment',
          name: '包含',
          isVisible: true,
          icon: 'Containment',
          style: { color: '#BDC6D0', border: 'solid' }
        }
      ],

      toolbar: [
        {
          name: 'recall',
          key: 'recall',
          icon: 'recall',
          type: 'button',
          tips: '重做',
          des: '',
          width: '20px',
          fn: this.handleUndo,
          disabled: true
        },
        {
          name: 'redo',
          key: 'redo',
          icon: 'redo',
          type: 'button',
          tips: '撤销',
          des: '',
          width: '20px',
          fn: this.handleRedo,
          disabled: true
        },
        {
          name: 'showModelPosition',
          key: 'showModelPosition',
          icon: 'icontreelocation',
          type: 'button',
          tips: '树上高亮',
          des: '',
          width: '20px',
          disabled: true,
          fn: this.showModelPostion
        },
        {
          name: 'iconlayout',
          key: 'iconlayout',
          icon: 'iconlayout',
          type: 'buttonList',
          tips: '布局',
          des: '',
          width: '36px',
          children: [
            {
              name: '横向'
            },
            {
              name: '纵向',
              disabled: true
            },
            {
              name: '放射状',
              disabled: true
            },
            {
              name: '按顺序',
              disabled: true
            },
            {
              name: '环形',
              disabled: true
            }
          ]
        },
        {
          name: 'deleteIcon',
          key: 'deleteIcon',
          icon: 'deleteIcon',
          type: 'button',
          tips: '删除',
          des: '',
          width: '20px',
          line: true,
          fn: this.deleteNode,
          disabled: true
        },
        {
          name: 'removeIcon',
          key: 'removeIcon',
          icon: 'removeIcon',
          type: 'button',
          tips: '移出',
          fn: this.removeNodeFromMap,
          des: '移出',
          width: '50px',
          line: true,
          disabled: true
        },
        {
          name: 'legend',
          key: 'legend',
          icon: 'legend',
          type: 'button',
          tips: '图例',
          des: '图例',
          width: '50px',
          line: true,
          fn: this.toggleLegend
        },
        {
          name: 'removeFromTable',
          key: 'removeFromTable',
          icon: 'removeFromTable',
          type: 'numberInput',
          tips: '层级',
          label: '层级：',
          width: '105px',
          line: true
        },
        {
          name: 'traceDirection',
          key: 'traceDirection',
          icon: 'traceDirection',
          tips: '向下分解',
          des: '向下分解',
          line: true,
          type: 'buttonList',
          children: [
            {
              name: '向下分解',
              fn: e => this.toggleTraceDirection(e, { direction: 'OUTGOING' })
            },
            {
              name: '向上溯源',
              fn: e => this.toggleTraceDirection(e, { direction: 'INCOMING' })
            }
          ]
        },
        {
          name: 'requirementField',
          key: 'requirementField',
          icon: 'requirementField',
          type: 'checkList',
          tips: '显示字段',
          des: '显示字段',
          line: true,
          columnIds: [
            { label: '名称', value: 'name' },
            { label: '需求类型', value: 'typeName' },
            { label: '需求ID', value: 'id' },
            { label: '批注', value: 'comment' },
            { label: '内容', value: 'content' }
          ]
        },
        {
          name: 'contentSet',
          key: 'contentSet',
          icon: 'contentSet',
          type: 'button',
          tips: '内容选择',
          des: '内容选择',
          line: true,
          fn: this.toggleContentSet
        },
        {
          name: 'search',
          key: 'search',
          icon: 'search',
          type: 'button',
          tips: '搜索',
          line: true,
          fn: this.toggleSearchBar
        },
        {
          name: 'zoomOut',
          key: 'zoomOut',
          icon: 'zoomOut',
          type: 'zoom',
          tips: '缩小'
        }
      ]
    };
  },
  computed: {
    relationTypeInput: function() {
      return this.legend
        .filter(item => item.isVisible === true)
        .map(item => item.name)
        .join();
    }
  },
  beforeMount() {
    this.diagram = app.graphTabs.find(item => item.id === this.mapId).graphNode;
  },
  mounted() {
    this.initDiagramInfo();
    this.$bus.onBatch(this.events);
  },
  beforeDestroy() {
    this.$bus.offBatch(this.events);
    this.destroy();
  },
  methods: {
    handleUndo() {
      console.log('undo');
      app.$messageBox.warn({
      //// id: 100,
        text: '功能开发中，敬请期待',
        title: '试用版'
      });
    },
    handleRedo() {
      app.$messageBox.warn({
      //// id: 100,
        text: '功能开发中，敬请期待',
        title: '试用版'
      });
    },

    handleDelete() {
      !this.btns.del.disabled && this.graph.actions['ctrl-d']();
    },
    initDiagramInfo() {
      let diagramInfo = utils.getDiagramInfo(this.diagram);
      let relationMap = utils.getRelationMap(this.diagram);
      //// this.traceHierarchy = diagramInfo.getDisplayDeepth();
      this.traceHierarchy = relationMap.getDisplayDepth();
      this.legend.forEach(item => {
        item.isVisible = relationMap.getRelationTypeVisible(item.key);
        //// const style = relationMap.getRelationStyle(item.key);
        //// item.style = {
        ////   color: style.getColor(),
        ////   border: style.getLineStyle()
        //// };
        item.style = {
          color: relationMap.getRelationStyle(item.key).toArray()[1],
          border: relationMap.getRelationStyle(item.key).toArray()[0]
        };
      });
      //// this.selectedColumnIds = diagramInfo.getDisplayContentList().toArray();
      this.selectedColumnIds = relationMap.getDisplayContentList().toArray();
      this.traceDirection = relationMap.getTraceBackDirection();
      utils.register(this.selectedColumnIds);
      if (relationMap.getInitialModel() != null) {
        this.addDiagramElementsToMap(relationMap.getInitialModel() );
      }
    },
    dragHandler() {
      console.log('triger drag');
      const dragData = treeUtil.dragData;
      if (SysMLUtilHelper.isRequirement(dragData.semanticModelBridge.elementCore.element)) {
        this.addDiagramElementsToMap(dragData);
        //// this.updateTable();
      }
    },
    handleTreeDragMouseover(event) {
      event.preventDefault();
      if (!treeUtil.dragData) return;
      const model = treeUtil.dragData.model;
      const typeName = modelApi.getModelTypeName(model);
      if (typeName === 'Requirement') {
        event.dataTransfer.dropEffect = 'copy';
      }
    },
    addDiagramElementsToMap(req) {
      if (!this.showGraph) {
        this.showGraph = true;
      }

      this.rootReq = req;
      this.loadMap(req);
    },
    //// 初始化map
    loadMap(req) {
      new Promise((resolve, reject) => {
        //// let rootDI = utils.initTraceData(this.diagram, req);
        let traceData = utils.TreeDataFromDI(req, this.diagram);
        if (Array.isArray(traceData) && traceData.length === 0){
          reject();
        }
        resolve(traceData);
      })
        .then(data => {
          const graph = utils.initMap.call(this, data);
          this.graph = graph;
          app.$bus.emit('project-modified');
        })
        .catch(err => {
          console.error(err);
        });
    },

    //// 刷新map
    refreshMap: throttle(function() {
      if (!this.graph || !this.visible || this.graph.destroyed) {
        return;
      }
      const req = this.rootReq;
      new Promise((resolve, reject) => {
        //// let rootDI = utils.initTraceData(this.diagram, req);
        let traceData = utils.TreeDataFromDI(req, this.diagram);
        if (Array.isArray(traceData) && traceData.length === 0){
          reject();
        }
        resolve(traceData);
      })
        .then(data => {
          this.graph.data(data);
          this.graph.render();
          this.graph.fitCenter();
        })
        .catch(err => {
          this.destroy();
          console.error(err);
        });
      //// app.$bus.emit('project-modified');
    }, 1000),
    onChange(checkValue) {
      let diff = difference(this.selectedColumnIds, checkValue);
      this.selectedColumnIds = checkValue;
      //// utils.getDiagramInfo(this.diagram).setDisplayContentByList(checkValue);
      utils.getRelationMap(this.diagram).setDisplayContentByList(checkValue);
      this.graph && this.graph.destroy();
      utils.register(this.selectedColumnIds);
      this.loadMap(this.rootReq);
      //// this.refreshMap();
    },
    //// 在节点上右键
    onContextMenu(sourceNode) {
      ContextMenu.popup({
        x: event.clientX,
        y: event.clientY,
        menuItems: utils.getContextMenu()
      })
        .then(res => {
          let graphNode = this.selectedNode.getModel().graphNode;
          let model = sourceNode.getModel();
          if (res.value === 'propertySetting') {
            //// app.ui.selectElement = graphNode;
            actions.getAction('showAttribute').run(graphNode);
          } else if (res.value === 'modelTreeSelect') {
            actions.getAction('selectOnTree').run(graphNode);
          } else if (res.value === 'removeCell') {
            this.removeNodeFromMap(model);
          } else if (res.value === 'deleteCell') {
            this.deleteNode(model);
          }
          //// this[menuItem.method] && this[menuItem.method](node.dataRef, menuItem);
        })
        .catch(err => err && console.error(err));
    },
    onAddMenu(sourceshape) {
      ContextMenu.popup({
        x: event.clientX,
        y: event.clientY,
        menuItems: utils.getAddMenuConfig()
      })
        .then(menuItem => {
          Promise.resolve()
            .then(() => {
              utils.addNode({
                typeName: menuItem.value,
                graphNode: sourceshape,
                diagram: this.diagram
              });
            })
            .then(() => {
              this.refreshMap();
              this.$bus.emit('model-add');
            });
        })
        .catch(err => err && console.error(err));
    },
    toggleContentSet() {
      this.contentSetShow = !this.contentSetShow;
    },
    toggleSearchBar() {
      this.searchBarShow = !this.searchBarShow;
    },
    toggleRelationTypeModal: throttle(function() {
      //// this.RelationTypeModalShow = !this.RelationTypeModalShow;
      if (!this.graph) {
        return;
      }
      const graph = this.graph;
      relationTypeModal
        .popup({
          legend: this.legend
        })
        .then(res => {
          if (Array.isArray(res)) {
            this.legend = res;
            let relationMap = utils.getRelationMap(this.diagram);
            res.forEach(edge => {
              relationMap.setRelationStyle(
                edge.key,
                edge.style.border,
                edge.style.color
              );
            });
            let visibleList = res.filter(item => item.isVisible === true);
            let visibleListIds = visibleList.map(item => item.key);
            relationMap.setRelationTypeVisibleByList(visibleListIds);
          }
          const edges = graph.getEdges();
          edges.forEach(edge => {
            const sourceNode = edge.get('sourceNode');
            const targetNode = edge.get('targetNode');
            const type = targetNode.getModel().relationType;
            const lineTypeFormat = {
              solid: [],
              dashed: [10, 10],
              dotted: [1, 1]
            };
            const lineObj = res.find(item => item.key === type);
            if (lineObj) {
              graph.updateItem(edge, {
                style: {
                  stroke: lineObj.style.color,
                  lineDash: lineTypeFormat[lineObj.style.border]
                }
              });
              graph.refreshItem(edge);
            }
          });
          this.refreshMap();
        });
    }, 1000),
    toggleElementTypeModal: throttle(function() {
      //// this.RelationTypeModalShow = !this.RelationTypeModalShow;
      elementTypeModal
        .popup({
          graphType: 'traceDiagram',
          defaultChecks: ['0-0-0']
        })
        .then(res => {
          this.requementTypeInput = res.checkedNodes
            .map(node => node.title)
            .join();
        });
    }, 1000),
    toggleScopeModal: throttle(function() {
      //// this.RelationTypeModalShow = !this.RelationTypeModalShow;
      const currentIds = [];
      currentIds.push(app.sysmlModel.id);
      selectMutiple
        .popup({
          currentIds,
          selectedElement: app.selectedElement,
          propertyKey: 'Not Exists PropertyKey',
          isNodeSelectable: node => {
            return node.type !== 'relationGroup';
          }
        })
        .then(res => {});
    }, 1000),
    //// 层级改变
    onNumberInputChange(value) {
      //// let diagramInfo = utils.getDiagramInfo(this.diagram);
      //// diagramInfo.setDisplayDeepth(value);
      let relationMap = utils.getRelationMap(this.diagram);
      relationMap.setDisplayDepth(value);
      this.deepChange();
    },
    deepChange: debounce(function() {
      console.log('追溯层级改变,刷新');
      this.refreshMap();
    }, 500),
    //// 切换追溯方向
    toggleTraceDirection(e, { direction }) {
      console.log('追溯方向改变');
      Promise.resolve()
        .then(() => {
          //// this.graph.set('defaultEdge', defaultEdge);
          let relationMap = utils.getRelationMap(this.diagram);
          if (direction === 'OUTGOING') {
            this.$set(this.legend[0], 'name', '追踪');
            this.$set(this.legend[1], 'name', '精华');
            this.$set(this.legend[2], 'name', '复制');
            this.$set(this.legend[3], 'name', '派生');
            this.$set(this.legend[4], 'name', '包含');
            this.$set(this.toolbar[8], 'des', '向下分解');
            relationMap.setTraceBackDirection('OUTGOING');
            this.traceDirection = 'OUTGOING';
          } else if (direction === 'INCOMING') {
            this.$set(this.legend[0], 'name', '被追踪');
            this.$set(this.legend[1], 'name', '被精华');
            this.$set(this.legend[2], 'name', '被复制');
            this.$set(this.legend[3], 'name', '被派生');
            this.$set(this.legend[4], 'name', '被包含');
            this.$set(this.toolbar[8], 'des', '向上溯源');
            relationMap.setTraceBackDirection('INCOMING');
            this.traceDirection = 'INCOMING';
          }
          const defaultEdge = {
            type: 'cubic-horizontal',
            style: {
              stroke: '#bcbcf2',
              lineWidth: 3,
              endArrow: this.traceDirection === 'OUTGOING',
              startArrow: this.traceDirection === 'INCOMING'
            }
          };
          this.graph.edge(edge => {
            return defaultEdge;
          });
        })
        .then(() => {
          this.refreshMap();
        });
    },
    zoomCanvas: function(param) {
      if (param) {
        if (this.canvasZoom >= 3) {
          return;
        }
        this.canvasZoom = this.canvasZoom + 0.1;
      } else {
        if (this.canvasZoom < 0.2) {
          return;
        }
        this.canvasZoom = this.canvasZoom - 0.1;
      }
      console.log('画布缩放系数', this.canvasZoom);
      this.graph.zoomTo(this.canvasZoom);
      //// this.graph.fitView();
    },
    onSearch(keyWord) {
      let nodes = this.graph.getNodes();
      if (keyWord.length > 100) {
        app.$messageBox.error({
          id: 140,
          text: '输入内容请控制在100个字符内'
        });
        return;
      }
      nodes.forEach(node => {
        let group = node.get('group');
        let shape = group.find(
          element => element.get('name') === 'search-shape'
        );
        shape.hide();
      });
      if (keyWord === '') {
        this.searchResult = 0;
        return;
      }
      if (nodes.length > 0) {
        let count = 0;
        nodes.forEach(node => {
          let model = node.getModel();
          if (model.searchKey.includes(keyWord)) {
            count += 1;
            let group = node.get('group');
            let shape = group.find(
              element => element.get('name') === 'search-shape'
            );
            shape.show();

          }
        });
        this.searchResult = count;
      }
    },
    btnClick(item) {
      if (item.type === 'button') {
        item.fn();
      }
    },
    //// 切换图例
    toggleLegend() {
      this.showLegend = !this.showLegend;
    },
    //// 属性设置

    //// 树上高亮
    showModelPostion() {
      let graphNode = this.selectedNode.getModel().graphNode;
      actions.getAction('selectOnTree').run(graphNode);
    },

    //// 移除
    removeNodeFromMap(model) {
      if (!model) {
        model = this.selectedNode.getModel();
      }
      let initialModel =  utils.getRelationMap(this.diagram).getInitialModel();

      utils.removeNode({ shape: model.graphNode, diagram: this.diagram });
      if (model.model  === initialModel) {
        this.destroy();
      } else {
        this.refreshMap();
      }
      //// graphUtil.post('/graph/shape/delete', { shape: model.UMLShape, diagram: this.diagram });
    },

    //// 删除
    deleteNode(model) {
      if (!model) {
        model = this.selectedNode.getModel();
      }
      let _this = this;
      app.$Confirm
        .popup({
          title: '删除',
          subTitle: `确定要删除吗?`,
          content: `以下需求将被删除`,
          subContent: `${model.name}`,
          explain: '删除后元素模型和图元均会被删除',
          status: 'warn'
        })
        .then(() => {
          model.graphNode.remove();
          //// const nodeModel = shapeApi.getShapeModel(model.UMLShape);
          //// modelApi.deleteModelElement({ model: nodeModel });
          if (_this.rootReq === model.model) {
            _this.destroy();
          } else {
            _this.refreshMap();
          }
          app.$bus.emit('model-delete', {});
        })
        .catch(e => {});
    },

    destroy() {
      this.showGraph = false;

      this.graph && !this.graph.destroyed  && this.graph.destroy();
    }
  }
};
</script>
<style lang="scss" scoped>
.container {
  height: 100%;
  width: 100%;
  background: linear-gradient(360deg, #f7f6f6 0%, #f8f8f8 100%);
  .toolbar {
    width: 100%;
    height: 28px;
    line-height: 28px;
    padding-left: 4px;
    font-size: 12px;
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    background: #d4ebf8;
    border-bottom: 1px solid #99b1c5;
    .toolbarDiv {
      display: flex;
      height: 28px;
      line-height: 28px;
      align-items: center;
    }
    .toolbarItem {
      display: flex;
      height: 24px;
      line-height: 24px;

      cursor: pointer;
      padding: 1px;
      &.disabled {
        opacity: 0.25;
        cursor: not-allowed;
      }

      &:hover {
        background: linear-gradient(
          180deg,
          #b9e3ff 0%,
          #47b3ff 55%,
          #80c8fe 100%
        );
        border: 1px solid #b1cee2;
        padding: 0px;
      }
      .itemContent {
        display: flex;
        align-items: center;
        text-align: center;
        height: 24px;
        line-height: 24px;
        font-size: 12px;
        &.ant-tooltip-open{
          font-size:12px;
        }
        ._top-btn {
          ._btn-img {
            margin-top: -2px;
          }
        }
        .scale {
          margin: 0 4px;
        }
      }
    }
    ._disabled {
      opacity: 0.5;
      cursor: not-allowed;
      &:hover {
        background: transparent;
        opacity: 0.2;
      }
    }
    .icon {
      width: 16px;
      height: 16px;
      margin: 4px 2px;
      display: inline-block;
      vertical-align: middle;
      background-size: 16px 16px;
      background-repeat: no-repeat;
      &.icon_showModelPosition {
        background-image: url('~statics/icons/table/showModelPosition.svg');
      }
      //// &.icon_requirementField{
      ////   background-image: url('~statics/icons/table/requirementField.svg');
      //// }
      &.icon_requirementField {
        background-image: url('~statics/images/mainpage/iconchoose.svg');
      }
      &.icon_addRequirement {
        background-image: url('~statics/icons/table/addRequirement.svg');
      }
      &.icon_layout {
        background-image: url('~statics/icons/table/iconlayout.svg');
      }
      &.icon_deleteRequirement {
        background-image: url('~statics/icons/table/deleteRequirement.svg');
      }
      &.icon_removeFromTable {
        background-image: url('~statics/icons/table/removeFromTable.svg');
      }
      &.icon_removeFromDiagram {
        background-image: url('~statics/icons/table/iconremovep.svg');
      }
      &.icon_contentSet {
        background-image: url('~statics/icons/table/iconcontentselection.svg');
      }
      &.icon_legend {
        background-image: url('~statics/images/sysml/Legend.svg');
      }
      &.icon_zoomOut {
        background-image: url('~statics/icons/app/toolbarreduce.svg');
      }
      &.icon_zoomIn {
        background-image: url('~statics/icons/app/toolbarenlarge.svg');
      }
      &.icon_search {
        background-image: url('~statics/icons/table/iconsearch.svg');
      }
      &.icon_traceDirection {
        background-image: url('~statics/icons/table/Tracingdirection.svg');
      }
    }
    .icon_topiconline {
      width: 1px;
      height: 25px;
      line-height: 32px;
      margin-left: 8px;
      border: 1px solid #b1cee2;
    }
    .iconbarline {
      margin-left: 8px;
    }
  }
  ._table {
    height: calc(100% - 72px);
    overflow: auto;
    width: calc(100vw - 240px);
    .ant-table-wrapper {
      width: 99%;
    }
  }
  .customRow {
    background-color: #ffffff;
  }

  .ant-table-row-cell-break-word {
    &.ReqId {
      span:last-child {
        opacity: 0.25;
      }
    }
  }

  .textCell {
    //// white-space: break-spaces;
    &.Name {
      .div_input,
      input {
        vertical-align: top;
        display: inline-block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        width: calc(90% - 10px);
      }
    }
  }
}

.toolbarItem {
  //// width: 24px;
  height: 24px;
  line-height: 24px;
  padding: 0px 4px;
  white-space: nowrap;
  cursor: pointer;
  //// &.button>div{
  ////   width: 24px;
  //// }
  &.disabled {
    opacity: 0.25;
    cursor: not-allowed;
  }
  &:hover {
    background: linear-gradient(107deg, #a3dbff 0%, #74c5f8 100%);
    box-shadow: inset 0px 0px 1px 1px #b1cee2;
    border: none;
    padding: 0px 4px;
  }
}
.allTable {
  overflow-y: auto;
  height: calc(100% - 75px);
}
.searchBar {
  height: 42px;
  background: #fafafa;
  padding-top: 9px;
  padding-bottom: 9px;
  padding-left: 15px;
  font-size: 12px;
  > * {
    vertical-align: middle;
  }
  > span {
    margin-right: 8px;
  }
  ._select {
    width: 100px;
    height: 26px;
    margin-right: 8px;
    .ant-select-selection--single {
      height: 26px;
      .ant-select-selection__rendered {
        line-height: 24px !important;
        font-size: 12px;
      }
    }
  }
  ._input {
    display: inline-block;
    width: 180px;
    .ant-input {
      height: 26px;
    }
    .ant-input-search-button {
      height: 26px;
      color: #44525b;
      background: linear-gradient(
        180deg,
        #e5f6ff 0%,
        #c8e3f3 100%,
        #cae4f3 100%,
        #abd7ef 100%
      );
      border-radius: 0px;
      border: 1px solid #b1cee2;
    }
  }
  .previous {
    margin-right: 8px;
    cursor: pointer;
  }
  .next {
    cursor: pointer;
  }
  .previousTip {
    position: relative;
    float: left;
    left: 400px;
    top: 30px;
    z-index: 99;
  }
  .nextTip {
    position: relative;
    float: left;
    left: 420px;
    top: 30px;
    z-index: 99;
  }
  .triangle {
    position: absolute;
    left: 20px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 5px;
    border-color: transparent transparent #434343 transparent;
  }
  .rectangle {
    position: absolute;
    width: 50px;
    height: 22px;
    background: #434343;
    box-shadow: 0px 3px 4px 0px rgba(0, 0, 0, 0.32);
    border-radius: 0px;
    font-size: 12px;
    color: #ffffff;
    line-height: 22px;
    text-align: center;
  }
}
.checkList {
  .ant-checkbox-group {
    font-size: 12px;
    display: flex;
    flex-direction: column;
    //// width: 5px;
    padding: 4px;
    label.ant-checkbox-wrapper {
      font-size: 12px;
      margin-left: 4px;
      &:hover {
        background: linear-gradient(
          180deg,
          #e7f5fe 0%,
          #b0deff 65%,
          #b2ddfd 100%
        );
        border: none;
      }
    }
  }
}
.numberInput {
  //// width:120px;

  div.ant-input-number {
    width: 60px;
    //// transform: translateY(-4px);
  }
}
.buttonList {
  .ant-dropdown-menu-item {
    //// height:24px;
    //// line-height: 24px;
    //// padding-left: 15px;
    padding: 10px;
    &:hover {
      background: linear-gradient(
        180deg,
        #e7f5fe 0%,
        #b0deff 65%,
        #b2ddfd 100%
      );
      border: none;
    }
  }
}
._dropdown {
  height: 24px;
}
.anticon-edit {
  visibility: hidden;
}
.subtool {
  position: absolute;
  top: 54px;
  left: 3px;
  width: 100%;
  border-top: 1px solid #99b1c5;
}
.subBar {
  position: relative;
  width: 100%;
  height: 42px;
  background: #fafafa;
  line-height: 42px;
  border-bottom: 1px solid #e4e4e4;
  display: flex;
  justify-content: space-between;
  padding-left: 20px;
  z-index: 2;
  .subBarItem {
    width: 30%;
    > div {
      display: inline-block;
      padding: 3px;
      width: 80%;
    }
    > span {
      margin-right: 8px;
      font-weight: 400;
    }
  }
  &._search {
    justify-content: left;
    padding-left: 20px;
    transform: translateZ(5px);
    z-index: 1;
  }
}
.graph {
  position: relative; //// tooltip 定位需要容器为相对定位
  height: 100%;
  #mountNode {
    height: 100%;
  }
  .legends {
    height: 166px;
    //// width: 109px;
    position: absolute;
    top: 10px;
    right: 10%;
    box-shadow: 0px 9px 28px 8px rgba(0, 0, 0, 0.05),
      0px 6px 16px 0px rgba(0, 0, 0, 0.08), 0px 3px 6px -4px rgba(0, 0, 0, 0.12);
    border: 1px solid #c2d1da;
    background: #ffffff;
    //// padding-left: 17px;
    padding-top: 4px;
    padding-left: 8px;
    padding-right: 8px;
    z-index: 2;
    .title {
      text-align: center;
      font-size: 12px;
      font-family: PingFangSC-Medium, PingFang SC;
      font-weight: 500;
      color: #000000;
      line-height: 20px;
      margin-bottom: 10px;
    }
    .legend {
      //// margin-left: 17px;
      margin-right: 10px;
      vertical-align: middle;
      width: 40px;
      height: 3px;
    }
  }
}
.empty {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  .text {
    font-size: 18px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: #919191;
  }
}
/deep/.g6-tooltip {
  padding: 4px 8px;
  font-size: 12px;
  font-family: MicrosoftYaHei;
  color: #ffffff;
  background: #434343;
  box-shadow: 0px 3px 4px 0px rgba(0, 0, 0, 0.32);
  border-radius: 0px;
}

.slide-enter-active {
  animation: slide-in 1s;
}
.slide-leave-active {
  animation: slide-in 1s reverse;
}
@keyframes slide-in {
  0% {
    transform: translate(0px, -60px);
  }
  100% {
    transform: translate(0px, 0px);
  }
}

</style>
